package com.cjd.common.utils;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.graphics.Rect;
import android.os.Build;
import android.util.TypedValue;
import android.view.DisplayCutout;
import android.view.View;

import java.lang.reflect.Method;
import java.util.List;

/**
 * @Author chenjidong
 * @email 374122600@qq.com
 * created 2019/11/26
 * description 刘海屏
 */
public class NotchScreenUtil {


    /**
     * 判断是否是华为刘海屏
     */
    public static boolean hasNotchInScreenAtHuawei(Context context) {
        boolean ret = false;
        try {
            ClassLoader cl = context.getClassLoader();
            Class<?> HwNotchSizeUtil = cl.loadClass("com.huawei.android.util.HwNotchSizeUtil");
            Method get = HwNotchSizeUtil.getMethod("hasNotchInScreen");
            ret = (Boolean) get.invoke(HwNotchSizeUtil);
            LogUtils.d("this Huawei device has notch in screen？" + ret);
        } catch (ClassNotFoundException e) {
            LogUtils.e(e);
        } catch (NoSuchMethodException e) {
            LogUtils.e(e);
        } catch (Exception e) {
            LogUtils.e(e);
        }
        return ret;
    }

    /**
     * 获取华为刘海的高
     *
     * @param context
     * @return
     */
    public static int getNotchSizeAtHuawei(Context context) {
        int[] ret = new int[]{0, 0};
        try {
            ClassLoader cl = context.getClassLoader();
            Class<?> HwNotchSizeUtil = cl.loadClass("com.huawei.android.util.HwNotchSizeUtil");
            Method get = HwNotchSizeUtil.getMethod("getNotchSize");
            ret = (int[]) get.invoke(HwNotchSizeUtil);

        } catch (ClassNotFoundException e) {
            LogUtils.e("getNotchSize ClassNotFoundException");
        } catch (NoSuchMethodException e) {
            LogUtils.e("getNotchSize NoSuchMethodException");
        } catch (Exception e) {
            LogUtils.e("getNotchSize Exception");
        }
        return ret[1];
    }

    public static boolean hasNotchInScreenAtOppo(Context context) {
        boolean hasNotch = context.getPackageManager().hasSystemFeature("com.oppo.feature.screen.heteromorphism");
        LogUtils.d("this OPPO device has notch in screen？" + hasNotch);
        return hasNotch;
    }

    public static int getNotchSizeAtOppo() {
        return 80;
    }


    public static final int NOTCH_IN_SCREEN_VOIO = 0x00000020;// 是否有凹槽
    public static final int ROUNDED_IN_SCREEN_VOIO = 0x00000008;// 是否有圆角

    public static boolean hasNotchInScreenAtVivo(Context context) {
        boolean ret = false;
        try {
            ClassLoader cl = context.getClassLoader();
            Class<?> FtFeature = cl.loadClass("com.util.FtFeature");
            Method get = FtFeature.getMethod("isFeatureSupport", int.class);
            ret = (Boolean) get.invoke(FtFeature, NOTCH_IN_SCREEN_VOIO);
            LogUtils.d("this VIVO device has notch in screen？" + ret);
        } catch (ClassNotFoundException e) {
            LogUtils.e(e);
        } catch (NoSuchMethodException e) {
            LogUtils.e(e);
        } catch (Exception e) {
            LogUtils.e(e);
        }
        return ret;
    }

    public static int getNotchSizeAtVivo(Context context) {
        return dp2px(context, 32);
    }


    /**
     * dp转px
     *
     * @param context
     * @param dpValue
     * @return
     */
    private static int dp2px(Context context, int dpValue) {
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dpValue, context.getResources().getDisplayMetrics());
    }

    /**
     * 获取手机厂商
     *
     * @return 手机厂商
     */

    public final static int DEVICE_BRAND_OPPO = 1;
    public final static int DEVICE_BRAND_HUAWEI = 2;
    public final static int DEVICE_BRAND_VIVO = 3;


    @SuppressLint("DefaultLocale")
    public static int getDeviceBrand() {
        String brand = android.os.Build.BRAND.trim().toUpperCase();
        if (brand.contains("HUAWEI")) {
            LogUtils.d("HUAWEI");
            return DEVICE_BRAND_HUAWEI;
        } else if (brand.contains("OPPO")) {
            LogUtils.d("OPPO");
            return DEVICE_BRAND_OPPO;
        } else if (brand.contains("VIVO")) {
            LogUtils.d("VIVO");
            return DEVICE_BRAND_VIVO;
        }
        return 0;
    }

    /**
     * 获取 刘海屏高度
     *
     * @param context Activity
     * @return 根据品牌返回不同高度 api 28以下续判断品牌 以上直接使用原生获取高度
     */
    public static int getNotchHeight(Activity context) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
            View root = context.getWindow().getDecorView();
            if (root.getRootWindowInsets() != null) {
                DisplayCutout displayCutout = root.getRootWindowInsets().getDisplayCutout();
                if (displayCutout != null) {
                    LogUtils.e("安全区域距离屏幕左边的距离 SafeInsetLeft:" + displayCutout.getSafeInsetLeft());
                    LogUtils.e("安全区域距离屏幕右部的距离 SafeInsetRight:" + displayCutout.getSafeInsetRight());
                    LogUtils.e("安全区域距离屏幕顶部的距离 SafeInsetTop:" + displayCutout.getSafeInsetTop());
                    LogUtils.e("安全区域距离屏幕底部的距离 SafeInsetBottom:" + displayCutout.getSafeInsetBottom());

                    List<Rect> rects = displayCutout.getBoundingRects();
                    if (rects == null || rects.size() == 0) {
                        LogUtils.e("不是刘海屏");
                    } else {
                        LogUtils.e("刘海屏数量:" + rects.size());
                        for (Rect rect : rects) {
                            LogUtils.e("刘海屏区域：" + rect);
                        }
                        return displayCutout.getSafeInsetTop();
                    }
                }
            }
        } else {
            int value = getDeviceBrand();

            if (value == DEVICE_BRAND_HUAWEI && hasNotchInScreenAtHuawei(context)) {
                return getNotchSizeAtHuawei(context);
            } else if (value == DEVICE_BRAND_OPPO && hasNotchInScreenAtOppo(context)) {
                return getNotchSizeAtOppo();
            } else if (value == DEVICE_BRAND_VIVO && hasNotchInScreenAtVivo(context)) {
                return getNotchSizeAtVivo(context);
            }
        }
        return 0;
    }

}
